package com.tju.ocean_ecology_website.controller;

import com.tju.ocean_ecology_website.dto.ServiceHoursListResponseDTO;
import com.tju.ocean_ecology_website.dto.ServiceHoursListResponseDTO.ServiceHourDetailDTO;
import com.tju.ocean_ecology_website.dto.ServiceHoursStatsDTO;

import com.tju.ocean_ecology_website.dto.ApiResponse;
import com.tju.ocean_ecology_website.dto.PageResult;
import com.tju.ocean_ecology_website.dto.ServiceHourRecordDTO;
import com.tju.ocean_ecology_website.dto.ServiceHoursQueryDTO;
import com.tju.ocean_ecology_website.dto.ServiceHoursTrendDTO;
import com.tju.ocean_ecology_website.dto.ServiceHoursTrendQueryDTO;
import com.tju.ocean_ecology_website.entity.Activity;
import com.tju.ocean_ecology_website.entity.User;
import com.tju.ocean_ecology_website.entity.VolunteerInfo;
import com.tju.ocean_ecology_website.entity.VolunteerServiceRecord;
import com.tju.ocean_ecology_website.mapper.UserMapper;
import com.tju.ocean_ecology_website.service.ActivityService;
import com.tju.ocean_ecology_website.service.UserService;
import com.tju.ocean_ecology_website.service.VolunteerInfoService;
import com.tju.ocean_ecology_website.service.VolunteerServiceRecordService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

import javax.annotation.Resource;

/**
 * 志愿者服务时长控制器
 */
@RestController
@RequestMapping("/api/volunteer")
public class VolunteerServiceHoursController {

    @Resource
    private UserService userService;

    @Resource
    private VolunteerInfoService volunteerInfoService;

    @Resource
    private VolunteerServiceRecordService volunteerServiceRecordService;

    @Resource
    private ActivityService activityService;

    @Resource
    private UserMapper userMapper;

    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 获取服务时长记录
     *
     * @param queryDTO 查询参数
     * @return 服务时长记录列表
     */
    /**
     * 获取服务时长统计数据
     *
     * @return 服务时长统计数据
     */
    @GetMapping("/hours/stats")
    public ResponseEntity<ApiResponse<ServiceHoursStatsDTO>> getServiceHoursStats() {
        // 获取当前用户ID
        final Long currentUserId = getCurrentUserId();

        // 查询志愿者信息
        VolunteerInfo volunteerInfo = volunteerInfoService.queryById(currentUserId);
        if (volunteerInfo == null) {
            // 如果没有找到志愿者信息，尝试通过用户ID查询
            VolunteerInfo query = new VolunteerInfo();
            query.setUserId(currentUserId);
            List<VolunteerInfo> volunteerInfos = volunteerInfoService.queryAllByLimit(query, PageRequest.of(0, 1));
            if (!volunteerInfos.isEmpty()) {
                volunteerInfo = volunteerInfos.get(0);
            } else {
                return ResponseEntity.badRequest().body(ApiResponse.error(400, "未找到志愿者信息"));
            }
        }

        // 获取总服务时长
        double totalHours = volunteerInfo.getVolunteerHours() != null ? volunteerInfo.getVolunteerHours() : 0;

        // 获取本月服务时长
        double monthHours = volunteerServiceRecordService.getMonthServiceHours(volunteerInfo.getId());

        // 获取排名情况
        String rank = volunteerServiceRecordService.getVolunteerRank(volunteerInfo.getId());

        // 获取志愿者等级信息
        Map<String, Object> levelInfo = volunteerServiceRecordService.getVolunteerLevel(totalHours);

        // 创建DTO
        ServiceHoursStatsDTO statsDTO = ServiceHoursStatsDTO.builder()
                .totalHours(totalHours)
                .monthHours(monthHours)
                .rank(rank)
                .level((String) levelInfo.get("level"))
                .nextLevel((String) levelInfo.get("nextLevel"))
                .nextLevelHours((Integer) levelInfo.get("nextLevelHours"))
                .hoursToNextLevel((Double) levelInfo.get("hoursToNextLevel"))
                .build();

        return ResponseEntity.ok(ApiResponse.success(statsDTO));
    }

    @GetMapping("/hours")
    public ResponseEntity<ApiResponse<ServiceHoursListResponseDTO>> getServiceHours(ServiceHoursQueryDTO queryDTO) {
        // 获取当前用户ID
        final Long currentUserId = getCurrentUserId();

        // 创建查询条件
        VolunteerServiceRecord recordQuery = new VolunteerServiceRecord();
        recordQuery.setVolunteerId(currentUserId);

        // 设置项目ID筛选
        if (queryDTO.getProjectId() != null) {
            recordQuery.setActivityId(queryDTO.getProjectId());
        }

        // 设置状态筛选
        if (queryDTO.getStatus() != null) {
            if ("verified".equals(queryDTO.getStatus())) {
                recordQuery.setStatus(1); // 已认证
            } else if ("pending".equals(queryDTO.getStatus())) {
                recordQuery.setStatus(0); // 待认证
            }
        }

        // 处理日期范围
        Date startDate = null;
        Date endDate = null;
        try {
            if (queryDTO.getStartDate() != null && !queryDTO.getStartDate().isEmpty()) {
                startDate = dateFormat.parse(queryDTO.getStartDate());
            }

            if (queryDTO.getEndDate() != null && !queryDTO.getEndDate().isEmpty()) {
                endDate = dateFormat.parse(queryDTO.getEndDate());
                // 将结束日期设置为当天的最后一刻
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(endDate);
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                endDate = calendar.getTime();
            }
        } catch (ParseException e) {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, "日期格式错误"));
        }

        // 查询服务时长记录
        PageRequest pageRequest = queryDTO.toPageRequest();
        Page<VolunteerServiceRecord> recordPage = volunteerServiceRecordService.queryByPage(recordQuery, pageRequest);

        // 转换为DTO
        List<ServiceHourDetailDTO> recordDTOs = new ArrayList<>();
        for (VolunteerServiceRecord record : recordPage.getContent()) {
            ServiceHourDetailDTO dto = ServiceHourDetailDTO.builder()
                    .id(record.getId())
                    .date(record.getServiceDate() != null ? dateFormat.format(record.getServiceDate()) : "")
                    .projectId(record.getActivityId())
                    .projectName(record.getActivityTitle())
                    .hours(record.getServiceHours() != null ? record.getServiceHours().doubleValue() : 0)
                    .status(record.getStatus() != null && record.getStatus() == 1 ? "verified" : "pending")
                    .remark(record.getDescription())
                    .build();

            // 获取活动组织信息
            if (record.getActivityId() != null) {
                Activity activity = activityService.queryById(record.getActivityId());
                if (activity != null) {
                    dto.setOrganizationId(activity.getOrganizationId());
                    // 这里应该设置组织名称，但需要查询组织信息
                    // 简化处理，直接使用活动标题作为服务类型
                    dto.setServiceType(activity.getTitle());
                }
            }

            recordDTOs.add(dto);
        }

        // 获取统计数据
        VolunteerInfo volunteerInfo = volunteerInfoService.queryById(currentUserId);
        if (volunteerInfo == null) {
            // 如果没有找到志愿者信息，尝试通过用户ID查询
            VolunteerInfo query = new VolunteerInfo();
            query.setUserId(currentUserId);
            List<VolunteerInfo> volunteerInfos = volunteerInfoService.queryAllByLimit(query, PageRequest.of(0, 1));
            if (!volunteerInfos.isEmpty()) {
                volunteerInfo = volunteerInfos.get(0);
            }
        }

        double totalHours = volunteerInfo != null && volunteerInfo.getVolunteerHours() != null ?
                volunteerInfo.getVolunteerHours() : 0;
        double monthHours = volunteerInfo != null ?
                volunteerServiceRecordService.getMonthServiceHours(volunteerInfo.getId()) : 0;
        String rank = volunteerInfo != null ?
                volunteerServiceRecordService.getVolunteerRank(volunteerInfo.getId()) : "暂无排名";

        ServiceHoursStatsDTO statsDTO = ServiceHoursStatsDTO.builder()
                .totalHours(totalHours)
                .monthHours(monthHours)
                .rank(rank)
                .build();

        // 创建响应DTO
        ServiceHoursListResponseDTO responseDTO = ServiceHoursListResponseDTO.builder()
                .total(recordPage.getTotalElements())
                .list(recordDTOs)
                .stats(statsDTO)
                .build();

        return ResponseEntity.ok(ApiResponse.success(responseDTO));
    }

    /**
     * 申请/登记服务时长
     *
     * @param request 申请参数
     * @return 申请结果
     */
    @PostMapping("/hours")
    public ResponseEntity<ApiResponse<Map<String, Object>>> applyServiceHours(@RequestBody Map<String, Object> request) {
        // 获取当前用户ID
        final Long currentUserId = getCurrentUserId();

        // 查询志愿者信息
        VolunteerInfo volunteerInfo = volunteerInfoService.queryById(currentUserId);
        Long volunteerId = currentUserId;
        if (volunteerInfo == null) {
            // 如果没有找到志愿者信息，尝试通过用户ID查询
            VolunteerInfo query = new VolunteerInfo();
            query.setUserId(currentUserId);
            List<VolunteerInfo> volunteerInfos = volunteerInfoService.queryAllByLimit(query, PageRequest.of(0, 1));
            if (!volunteerInfos.isEmpty()) {
                volunteerInfo = volunteerInfos.get(0);
                volunteerId = volunteerInfo.getId();
            } else {
                return ResponseEntity.badRequest().body(ApiResponse.error(400, "未找到志愿者信息"));
            }
        } else {
            volunteerId = volunteerInfo.getId();
        }

        // 创建服务记录
        VolunteerServiceRecord record = new VolunteerServiceRecord();
        record.setVolunteerId(volunteerId);

        // 设置项目ID
        if (request.containsKey("projectId")) {
            Long projectId = Long.valueOf(request.get("projectId").toString());
            record.setActivityId(projectId);

            // 查询活动信息
            Activity activity = activityService.queryById(projectId);
            if (activity != null) {
                record.setActivityTitle(activity.getTitle());
            }
        }

        // 设置服务时长
        if (request.containsKey("hours")) {
            Double hours = Double.valueOf(request.get("hours").toString());
            record.setServiceHours(hours.intValue()); // 转换为int
        } else {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, "服务时长不能为空"));
        }

        // 设置服务日期
        if (request.containsKey("date")) {
            try {
                Date serviceDate = dateFormat.parse(request.get("date").toString());
                record.setServiceDate(serviceDate);
            } catch (ParseException e) {
                return ResponseEntity.badRequest().body(ApiResponse.error(400, "日期格式错误"));
            }
        } else {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, "服务日期不能为空"));
        }

        // 设置备注
        if (request.containsKey("remark")) {
            record.setDescription(request.get("remark").toString());
        }

        // 设置状态和时间
        record.setStatus(0); // 待审核
        Date now = new Date();
        record.setCreateTime(now);
        record.setUpdateTime(now);

        // 保存服务时长记录
        VolunteerServiceRecord savedRecord = volunteerServiceRecordService.insert(record);

        // 创建响应
        Map<String, Object> response = new HashMap<>();
        response.put("id", savedRecord.getId());
        response.put("status", "pending");

        return ResponseEntity.ok(ApiResponse.success(response, "服务时长登记成功，等待审核"));
    }

    /**
     * 获取服务时长详情
     *
     * @param id 记录ID
     * @return 服务时长详情
     */
    @GetMapping("/hours/{id}")
    public ResponseEntity<ApiResponse<VolunteerServiceRecord>> getServiceHourDetail(@PathVariable("id") Long id) {
        // 查询服务时长记录
        VolunteerServiceRecord record = volunteerServiceRecordService.queryById(id);
        if (record == null) {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, "服务时长记录不存在"));
        }

        return ResponseEntity.ok(ApiResponse.success(record));
    }

    /**
     * 获取服务时长趋势
     *
     * @param range 时间范围，可选值：week（一周）、month（一个月）、year（一年）
     * @return 服务时长趋势
     */
    @GetMapping("/hours/trends")
    public ResponseEntity<ApiResponse<ServiceHoursTrendDTO>> getServiceHoursTrend(@RequestParam(value = "range", defaultValue = "month") String range) {
        // 获取当前用户ID
        final Long currentUserId = getCurrentUserId();

        // 查询志愿者信息
        VolunteerInfo volunteerInfo = volunteerInfoService.queryById(currentUserId);
        Long volunteerId = currentUserId;
        if (volunteerInfo == null) {
            // 如果没有找到志愿者信息，尝试通过用户ID查询
            VolunteerInfo query = new VolunteerInfo();
            query.setUserId(currentUserId);
            List<VolunteerInfo> volunteerInfos = volunteerInfoService.queryAllByLimit(query, PageRequest.of(0, 1));
            if (!volunteerInfos.isEmpty()) {
                volunteerInfo = volunteerInfos.get(0);
                volunteerId = volunteerInfo.getId();
            }
        } else {
            volunteerId = volunteerInfo.getId();
        }

        // 获取当前日期
        final LocalDate today = LocalDate.now();
        LocalDate startDate;
        DateTimeFormatter formatter;
        int dataPoints;

        // 根据时间范围确定开始日期和日期格式
        switch (range) {
            case "week":
                // 过去7天
                startDate = today.minusDays(6);
                formatter = DateTimeFormatter.ofPattern("MM-dd");
                dataPoints = 7;
                break;
            case "year":
                // 过去12个月
                startDate = today.withDayOfMonth(1).minusMonths(11);
                formatter = DateTimeFormatter.ofPattern("yyyy-MM");
                dataPoints = 12;
                break;
            case "month":
            default:
                // 过去30天
                startDate = today.minusDays(29);
                formatter = DateTimeFormatter.ofPattern("MM-dd");
                dataPoints = 30;
                break;
        }

        // 生成日期列表和时长列表
        List<String> dates = new ArrayList<>();
        List<Double> hours = new ArrayList<>();

        // 初始化日期和时长列表
        for (int i = 0; i < dataPoints; i++) {
            if (range.equals("year")) {
                LocalDate date = startDate.plusMonths(i);
                dates.add(date.format(formatter));
            } else {
                LocalDate date = startDate.plusDays(i);
                dates.add(date.format(formatter));
            }
            hours.add(0.0); // 初始化时长为0
        }

        // 转换为Date类型以便于查询
        Date startDateObj = Date.from(startDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
        Date endDateObj = Date.from(today.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());

        // 查询服务记录
        List<VolunteerServiceRecord> records = volunteerServiceRecordService.queryByVolunteerIdAndDateRange(
                volunteerId, startDateObj, endDateObj, Integer.valueOf(1)); // 只查询已通过的记录

        // 统计每个日期的服务时长
        for (VolunteerServiceRecord record : records) {
            if (record.getServiceDate() == null || record.getServiceHours() == null) continue;

            // 转换为LocalDate
            LocalDate recordDate = record.getServiceDate().toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDate();

            int index;
            if (range.equals("year")) {
                // 计算与开始日期的月数差
                index = (int) ChronoUnit.MONTHS.between(startDate, recordDate.withDayOfMonth(1));
                if (index >= 0 && index < dataPoints) {
                    hours.set(index, hours.get(index) + record.getServiceHours());
                }
            } else {
                // 计算与开始日期的天数差
                index = (int) ChronoUnit.DAYS.between(startDate, recordDate);
                if (index >= 0 && index < dataPoints) {
                    hours.set(index, hours.get(index) + record.getServiceHours());
                }
            }
        }

        // 创建趋势DTO
        ServiceHoursTrendDTO trendDTO = new ServiceHoursTrendDTO();
        trendDTO.setDates(dates);
        trendDTO.setHours(hours.stream().map(Double::intValue).collect(Collectors.toList()));

        return ResponseEntity.ok(ApiResponse.success(trendDTO));
    }

    /**
     * 导出服务时长记录
     *
     * @param projectId 项目ID（可选）
     * @param status 状态（可选）
     * @param startDate 开始日期（可选）
     * @param endDate 结束日期（可选）
     * @return Excel文件
     */
    @GetMapping("/hours/export")
    public ResponseEntity<byte[]> exportServiceHours(
            @RequestParam(required = false) Long projectId,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {

        // 获取当前用户ID
        final Long currentUserId = getCurrentUserId();

        // 查询志愿者信息
        VolunteerInfo volunteerInfo = volunteerInfoService.queryById(currentUserId);
        Long volunteerId = currentUserId;
        if (volunteerInfo == null) {
            // 如果没有找到志愿者信息，尝试通过用户ID查询
            VolunteerInfo query = new VolunteerInfo();
            query.setUserId(currentUserId);
            List<VolunteerInfo> volunteerInfos = volunteerInfoService.queryAllByLimit(query, PageRequest.of(0, 1));
            if (!volunteerInfos.isEmpty()) {
                volunteerInfo = volunteerInfos.get(0);
                volunteerId = volunteerInfo.getId();
            }
        } else {
            volunteerId = volunteerInfo.getId();
        }

        // 创建查询条件
        VolunteerServiceRecord recordQuery = new VolunteerServiceRecord();
        recordQuery.setVolunteerId(volunteerId);

        // 设置项目ID筛选
        if (projectId != null) {
            recordQuery.setActivityId(projectId);
        }

        // 设置状态筛选
        if (status != null) {
            if ("verified".equals(status)) {
                recordQuery.setStatus(1); // 已认证
            } else if ("pending".equals(status)) {
                recordQuery.setStatus(0); // 待认证
            }
        }

        // 处理日期范围
        Date startDateObj = null;
        Date endDateObj = null;
        try {
            if (startDate != null && !startDate.isEmpty()) {
                startDateObj = dateFormat.parse(startDate);
            }

            if (endDate != null && !endDate.isEmpty()) {
                endDateObj = dateFormat.parse(endDate);
                // 将结束日期设置为当天的最后一刻
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(endDateObj);
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                endDateObj = calendar.getTime();
            }
        } catch (ParseException e) {
            return ResponseEntity.badRequest().body(new byte[0]);
        }

        // 查询服务时长记录
        List<VolunteerServiceRecord> records;
        if (startDateObj != null && endDateObj != null) {
            // 如果有日期范围，使用日期范围查询
            records = volunteerServiceRecordService.queryByVolunteerIdAndDateRange(
                    volunteerId, startDateObj, endDateObj, recordQuery.getStatus() != null ? recordQuery.getStatus() : null);
        } else {
            // 否则使用导出方法
            records = volunteerServiceRecordService.exportServiceHours(recordQuery);
        }

        // 创建Excel工作簿
        try (Workbook workbook = new XSSFWorkbook()) {
            // 创建工作表
            Sheet sheet = workbook.createSheet("服务时长记录");

            // 创建标题行样式
            CellStyle headerStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);

            // 创建标题行
            Row headerRow = sheet.createRow(0);
            String[] headers = {"序号", "日期", "项目名称", "组织名称", "服务类型", "服务时长(小时)", "状态", "备注"};
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }

            // 填充数据
            int rowNum = 1;
            for (VolunteerServiceRecord record : records) {
                Row row = sheet.createRow(rowNum++);

                row.createCell(0).setCellValue(rowNum - 1);

                // 格式化日期
                String dateStr = record.getServiceDate() != null ?
                        dateFormat.format(record.getServiceDate()) : "";
                row.createCell(1).setCellValue(dateStr);

                // 项目名称
                String projectName = record.getActivityTitle() != null ?
                        record.getActivityTitle() : "";
                row.createCell(2).setCellValue(projectName);

                // 组织名称和服务类型
                String organizationName = "";
                String serviceType = "";
                if (record.getActivityId() != null) {
                    Activity activity = activityService.queryById(record.getActivityId());
                    if (activity != null) {
                        // 这里应该查询组织名称，但简化处理
                        organizationName = activity.getOrganizationId() != null ?
                                activity.getOrganizationId().toString() : "";
                        serviceType = activity.getTitle() != null ? activity.getTitle() : "";
                    }
                }
                row.createCell(3).setCellValue(organizationName);
                row.createCell(4).setCellValue(serviceType);

                // 服务时长
                row.createCell(5).setCellValue(record.getServiceHours() != null ?
                        record.getServiceHours() : 0);

                // 状态
                String statusStr = "待认证";
                if (record.getStatus() != null) {
                    if (record.getStatus() == 1) {
                        statusStr = "已认证";
                    } else if (record.getStatus() == 2) {
                        statusStr = "已拒绝";
                    }
                }
                row.createCell(6).setCellValue(statusStr);

                // 备注
                row.createCell(7).setCellValue(record.getDescription() != null ?
                        record.getDescription() : "");
            }

            // 调整列宽
            for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
            }

            // 将工作簿写入字节数组
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);

            // 设置HTTP头
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
            httpHeaders.setContentDispositionFormData("attachment", "service_hours.xlsx");

            return ResponseEntity.ok()
                    .headers(httpHeaders)
                    .body(outputStream.toByteArray());
        } catch (IOException e) {
            return ResponseEntity.badRequest().body(new byte[0]);
        }
    }

    /**
     * 获取当前登录用户的ID
     *
     * @return 当前用户ID
     */
    private Long getCurrentUserId() {
        // 从 SecurityContextHolder 获取当前认证信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated()) {
            // 获取用户名
            String username = authentication.getName();
            // 通过用户名查询用户信息
            User user = userMapper.findByUsername(username);
            if (user != null) {
                return user.getId();
            }
        }
        // 如果无法获取用户信息，抛出异常
        throw new RuntimeException("未能获取当前用户信息，请确保用户已登录");
    }
}
